<?php
/**
 * Created by PHPStorm
 * User: xiest
 * Date: 2021/6/7
 * Email: <939369942@qq.com>
 */
namespace app\common\middleware;

use app\common\repositories\user\UserRepository;
use app\Request;
use basic\exceptions\AuthException;
use Firebase\JWT\ExpiredException;
use think\exception\ValidateException;
use basic\services\JwtTokenService;

class UserTokenMiddleware{

    public function handle(Request $request,\Closure $next,$flag)
    {
        $flag = $flag ?? true;

        try {

            // todo 根据token 换取uid！

            $token = trim($request->header('X-Token'));
            if (!$token) $token = trim($request->param('token', ''));
            if (!$token) throw new AuthException('请登录');

            /** @var UserRepository $rep */
            $rep = app()->make(UserRepository::class);
            $service = new JwtTokenService();

            try {
                $payload = $service->parseToken($token);
                $rep->checkToken($token);
            } catch (ExpiredException $e) {
               // $rep->checkToken($token);
                $payload = $service->decode($token);
            } catch (\Throwable $e) {
                throw new AuthException('token 已过期');
            }

            if ('user' != $payload->jti[1])
                throw new AuthException('无效的token');

            $user = $rep->get($payload->jti[0]);
            if (!$user) throw new AuthException('用户不存在');

            if(isset($user->status) && !$user->status){
                throw new ValidateException('用户被禁用，请联系管理员');
            }
            $user->append(['lawyer_id']);

            $request->macro('uid', function () use ($user) {
                return $user['uid'];
            });

            $request->macro('userInfo', function () use ($user) {
                return $user;
            });

            $request->macro('isLogin',function (){
                return true;
            });

            //更新token
            $rep->updateToken($token);
            $rep->loginAfter($user);

        }catch (\Throwable $e)
        {
            if($flag) throw $e;

            $request->macro('uid', function ()use($e){
                throw new AuthException('未登录');
            });

            $request->macro('userInfo', function ()use($e){
                throw new AuthException('未登录');
            });

            $request->macro('isLogin',function (){
                return false;
            });
        }

        return $next($request);
    }

    static function getUid($token, $strict = false, $jwtSecret = '')
    {
        if (env('APP_ENV') != 'production' && is_numeric($token)) {
            return $token;
        }
        $jwtSecret = empty($jwtSecret) ? env("JWT_SECRET") : $jwtSecret;
        //截取基础信息数组
        $info_str = substr(strstr($token, '.'), 1);
        $param_str = base64_decode($info_str);
        //获取token中的秘钥字符串
        $secret = strstr($token, '.', true);

        //校验token是否合法
        // if ($secret != base64_encode(hash_hmac('SHA256', $param_str, $jwtSecret, true))) {
        //     throw new ValidateException('token 有误');
        // }
        //将url query参数存到数组中
        parse_str($param_str, $param_arr);


        if (!isset($param_arr['user_id']) || !$param_arr['user_id']) {
            throw new ValidateException('登录状态失效');
        }


        return $param_arr['user_id'];
    }

}